﻿using System;
using System.Collections.Generic;
using System.Text;
using net.veekee.common;
using System.Text.RegularExpressions;
using net.veekee.logprocessor.plugin.rules;

namespace net.veekee.logprocessor.plugin.context
{
    public struct ShortFileContext
    {
        public long ID;
        public String Name;
        public String Header;
        public bool Append;
        public String Format;
        public String Encoding;
    }

    public class FileContext
    {
        private String pattern = null;
        public String NamePattern
        {
            get
            {
                return this.pattern;
            }
            set
            {
                this.pattern = value;
                this.Rename();
            }
        }

        private String filename = null;
        public String Name
        {
            get
            {
                return this.filename;
            }
        }
        private ShortFileContext context;
        public ShortFileContext Context
        {
            get
            {
                return this.context;
            }
        }

        private String header = null;
        public String Header
        {
            get
            {
                return this.header;
            }
            set
            {
                this.header = value;
                this.CreateNewContext();
            }
        }

        private bool append = false;
        public bool Append
        {
            get
            {
                return this.append;
            }
            set
            {
                this.append = value;
                this.context.Append = value;
            }
        }

        private String format = null;
        public String Format
        {
            get
            {
                return this.format;
            }
            set
            {
                this.format = value;
                this.context.Format = value;
            }
        }

        private String encoding = null;
        public String Encoding
        {
            get
            {
                return this.encoding;
            }
            set
            {
                this.encoding = value;
                this.context.Encoding = value;
            }
        }

        public bool IsValid
        {
            get
            {
                return (this.header != null || this.filename != null);
            }
        }

        public FileContext(String fname)
        {
            this.context = new ShortFileContext();
            this.Header = Options.GetInstance().Get("output.fields");
            this.Format = Options.GetInstance().Get("output.format");
            this.Encoding = Options.GetInstance().Get("output.encoding");
            this.Append = Options.GetInstance().IsEnabled("output.append");
            this.NamePattern = fname;
        }

        public void Rename()
        {
            String newFilename = FileContext.GetFileName(this.pattern, ProcessorContext.GetInstance().Input);
            if (newFilename == null)
                return;
            if (this.filename != null)
            {
                if (this.filename.Equals(newFilename))
                    return;
            }
            this.filename = FileContext.GetFileName(this.pattern, ProcessorContext.GetInstance().Input);
            this.CreateNewContext();
        }

        private void CreateNewContext()
        {
            if (! this.IsValid)
                return;
            ShortFileContext sfc = new ShortFileContext();
            sfc.ID = ProcessorContext.GetInstance().AvailableShortOutputs.ItemCount;
            sfc.Name = this.filename;
            sfc.Header = this.header;
            sfc.Format = this.context.Format;
            sfc.Encoding = this.context.Encoding;
            sfc.Append = this.context.Append;
            ProcessorContext.GetInstance().AvailableShortOutputs.Set<ShortFileContext>(sfc.ID, sfc);
            this.context = sfc;
        }

        private static String GetFileName_Replace(String pattern, String parameter, String value)
        {
            return Regex.Replace(pattern, "%" + parameter + "%", value, RegexOptions.IgnoreCase);
        }

        public static String GetFileName(String pattern, String source)
        {
            if (source != null)
            {
                if (source.Length > 0)
                {
                    System.IO.FileInfo fsource = new System.IO.FileInfo(source);
                    pattern = GetFileName_Replace(pattern, "Input.FullFileName", fsource.FullName);
                    pattern = GetFileName_Replace(pattern, "Input.Directory", fsource.Directory.FullName);
                    pattern = GetFileName_Replace(pattern, "Input.FileName", fsource.Name);
                    pattern = GetFileName_Replace(pattern, "Input.FileName.NoExt", fsource.Name.Substring(0, fsource.Name.Length - fsource.Extension.Length));
                    pattern = GetFileName_Replace(pattern, "Input.FileName.Ext", fsource.Extension);
                }
                else
                {
                    pattern = GetFileName_Replace(pattern, "Input.FullFileName", "");
                    pattern = GetFileName_Replace(pattern, "Input.Directory", "");
                    pattern = GetFileName_Replace(pattern, "Input.FileName", "");
                    pattern = GetFileName_Replace(pattern, "Input.FileName.NoExt", "");
                    pattern = GetFileName_Replace(pattern, "Input.FileName.Ext", "");
                }
            }
            else
            {
                pattern = GetFileName_Replace(pattern, "Input.FullFileName", "");
                pattern = GetFileName_Replace(pattern, "Input.Directory", "");
                pattern = GetFileName_Replace(pattern, "Input.FileName", "");
                pattern = GetFileName_Replace(pattern, "Input.FileName.NoExt", "");
                pattern = GetFileName_Replace(pattern, "Input.FileName.Ext", "");
            }
            foreach (String envkey in RuleEnvironment.GetInstance().Fields.Keys)
            {
                pattern = GetFileName_Replace(pattern, "Environment." + envkey, RuleEnvironment.GetInstance().Fields.Get(envkey));
            }
            String[] filters = Options.GetInstance().Get("rules.filter", "").Split(new char[] { ';' });
            if (filters.Length > 0)
                pattern = GetFileName_Replace(pattern, "Rules.Filter", filters[0]);
            return pattern;
        }
    }
}
